package com.atguigu.edu.util;


import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import common.GmallConfig;
import org.apache.commons.lang3.StringUtils;
import org.apache.flink.api.java.tuple.Tuple2;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import redis.clients.jedis.Jedis;

/**
 * @author Felix
 * @date 2022/8/27
 * 查询维度的工具类
 */
public class DimUtil {

    public static JSONObject getDimInfo(Connection conn, String tableName, String id){
        return getDimInfo(conn,tableName,Tuple2.of("id",id));
    }
    /**
     * @param conn
     * @param tableName
     * @param columnNameAndValues
     * @return
     * 查询维度数据优化：旁路缓存
     * 思路：首先先从缓存中查询维度数据，如果缓存中存在，直接将缓存中的维度数据，作为返回值返回(缓存命中)；
     *      如果缓存中没有找到对应的维度信息，发送请求到phoenix表中将维度查询出来，并将查询出来的维度放到
     *      缓存中缓存起来，方便下次使用。
     * 选型：
     *      redis   √
     *          性能不错，操作方便
     *      状态
     *          性能优，但是操作维护不方便
     * Redis中数据类型
     *      String
     * Redis中的key
     *      dim:维度表表名:主键1_主键2
     * 注意：
     *      redis缓存ttl，1day
     *      如果业务数据库维度表发生了变化，需要将缓存中缓存的数据清空
     */
    public static JSONObject getDimInfo(Connection conn, String tableName, Tuple2<String,String> ... columnNameAndValues){
        //拼接从Redis中查询数据的key
        StringBuilder redisKey = new StringBuilder("dim:"+tableName.toLowerCase()+":");
        //拼接查询维度的SQL
        StringBuilder selectSql = new StringBuilder("select * from "+ GmallConfig.PHOENIX_SCHEMA +"."+tableName+" where ");
        for (int i = 0; i < columnNameAndValues.length; i++) {
            Tuple2<String, String> columnNameAndValue = columnNameAndValues[i];
            String columnName = columnNameAndValue.f0;
            String columnValue = columnNameAndValue.f1;
            selectSql.append(columnName + "='"+columnValue+"'");
            redisKey.append(columnValue);
            if(i < columnNameAndValues.length - 1){
                selectSql.append(" and ");
                redisKey.append("_");
            }
        }

        Jedis jedis = null;
        String dimInfoStr = null;
        JSONObject dimJsonObj = null;
        //先从Redis中查询
        try {
            jedis = RedisUtil.getJedis();
            dimInfoStr = jedis.get(redisKey.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }

        if(StringUtils.isNotEmpty(dimInfoStr)){
            //缓存命中
            dimJsonObj = JSON.parseObject(dimInfoStr);
        }else{
            //在Redis缓存没有查到数据，发送请求到phoenix表中查询数据
            System.out.println("到phoenix表中查询维度数据的SQL:" + selectSql);
            //底层还是通过phoenixUtil工具类中的方法 到phoenix表中查询数据
            List<JSONObject> jsonObjList = PhoenixUtil.queryList(conn, selectSql.toString(), JSONObject.class);
            if(jsonObjList != null && jsonObjList.size() > 0){
                dimJsonObj = jsonObjList.get(0);
                //将查询出来的维度数据 放到Redis中缓存起来
                if(jedis != null){
                    jedis.setex(redisKey.toString(),3600*24,dimJsonObj.toJSONString());
                }
            }else{
                System.out.println("在phoenix表中没有找到对应的维度数据");
            }
        }

        if(jedis != null){
            System.out.println("~~~关闭Jedis客户端~~~");
            jedis.close();
        }

        return dimJsonObj;
    }
    //从phoenix表中查询维度数据  没有任何优化
    public static JSONObject getDimInfoNoCache(Connection conn, String tableName, Tuple2<String,String> ... columnNameAndValues){

        //拼接查询维度的SQL
        StringBuilder selectSql = new StringBuilder("select * from "+ GmallConfig.PHOENIX_SCHEMA +"."+tableName+" where ");
        for (int i = 0; i < columnNameAndValues.length; i++) {
            Tuple2<String, String> columnNameAndValue = columnNameAndValues[i];
            String columnName = columnNameAndValue.f0;
            String columnValue = columnNameAndValue.f1;
            selectSql.append(columnName + "='"+columnValue+"'");
            if(i < columnNameAndValues.length - 1){
                selectSql.append(" and ");
            }
        }
        System.out.println("到phoenix表中查询维度数据的SQL:" + selectSql);
        //底层还是通过phoenixUtil工具类中的方法 到phoenix表中查询数据
        List<JSONObject> jsonObjList = PhoenixUtil.queryList(conn, selectSql.toString(), JSONObject.class);
        JSONObject dimJsonObj = null;
        if(jsonObjList != null && jsonObjList.size() > 0){
            dimJsonObj = jsonObjList.get(0);
        }else{
            System.out.println("在phoenix表中没有找到对应的维度数据");
        }
        return dimJsonObj;
    }

    public static void delCached(String tableName,String id){
        String redisKey = "dim:"+tableName.toLowerCase()+":"+id;
        System.out.println(redisKey);
        Jedis jedis = null;
        try {
            jedis = RedisUtil.getJedis();
            jedis.del(redisKey);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("从Redis中删除缓存数据发生了异常");
        } finally {
            if(jedis != null){
                System.out.println("~~~删除缓存数据后，关闭Jedis客户端~~~");
                jedis.close();
            }
        }
    }

    public static void main(String[] args) throws SQLException {
        DruidDataSource dataSource = DruidDSUtil.createDataSource();
        Connection conn = dataSource.getConnection();
        // System.out.println(getDimInfoNoCache(conn, "dim_base_trademark",Tuple2.of("id","1")));
        // System.out.println(getDimInfo(conn, "dim_base_trademark",Tuple2.of("id","1")));
        System.out.println(getDimInfo(conn, "dim_base_trademark","1"));
    }
}